package com.podcstr.dao;

import com.podcstr.entity.Podcast;
import org.apache.log4j.Logger;

import javax.persistence.NoResultException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author azim
 * @since 5/16/13 
 */
public class PodcastDaoImpl extends GenericDaoImpl<Podcast, Long> implements PodcastDao {

    private final Logger log = Logger.getLogger(UserDaoImpl.class);

    @Override
    public void toggleAccess(long podcastID) {

        Podcast podcast = getEntityManager().find(Podcast.class, podcastID);

        if (podcast.isAccessable() == true) {
            podcast.setAccessable(false);
        } else {
            podcast.setAccessable(true);
        }
        getEntityManager().merge(podcast);

        log.info(new Date() + " : Podcast with id : " + podcastID + " has now accessable value of " + podcast.isAccessable());
    }

    @Override
    public Podcast findByPodcastName(String podcastName) {

        Podcast podcast = null;

        try {

            podcast = (Podcast) (getEntityManager().createNamedQuery("tb_podcasts.findByName").setParameter("name", podcastName).getSingleResult());
        } catch (NoResultException noe) {

            podcast = null;
        }

        if (podcast != null) {
            log.info(new Date() + " : Returning Podcast with name : " + podcastName);
        }
        return podcast;
    }

    @Override
    public List<Podcast> findByUserId(long userId) {

        List<Podcast> podcasts = getEntityManager().createQuery("SELECT p FROM Podcast p WHERE p.user.id=:userId")
                .setParameter("userId", userId)
                .getResultList();

        if (podcasts.size() != 0) {
            log.info(new Date() + " : Returning list of Podcasts by user with id : " + userId);
        } else {
            podcasts = null;
        }

        return podcasts;
    }

    @Override
    public List<Podcast> findByTags(String tag) {

        List<Podcast> podcasts = getEntityManager().createQuery("SELECT p FROM Podcast p WHERE LOCATE(p.tags, :tag) > 0")
                .setParameter("tag", tag)
                .getResultList();

        if (podcasts.size() != 0) {
            log.info(new Date() + " : Returning list of Podcasts by tag : " + tag);
        } else {
            podcasts = null;
        }

        return podcasts;
    }

    @Override
    public List<Podcast> findByCategoryId(long categoryId) {

        List<Podcast> podcasts = getEntityManager().createQuery("SELECT p FROM Podcast p WHERE (p.category.id=:categoryId OR p.category.parent=:categoryId) AND p.accessable=true")
                .setParameter("categoryId", categoryId)
                .getResultList();

        if (podcasts.size() != 0) {
            log.info(new Date() + " : Returning list of Podcasts of category with id : " + categoryId);
        } else {
            podcasts = null;
        }

        return podcasts;
    }

    @Override
    public long countPodcastByUserId(long userId) {

        Long count = (Long) getEntityManager().createQuery("SELECT count(p) FROM Podcast p WHERE p.user.id=:userId")
                                                .setParameter("userId", userId).getSingleResult();

        if(count == null)
        {
            count = Long.valueOf(0);
        }

        log.info(new Date() + " : Total Uploaded podcast by user with id " + userId + " is : " + count);
        return count;
    }

    @Override
    public List<Podcast> searchPodcast(String word) {

        List<Podcast> podcasts = getEntityManager()
                                    .createQuery("SELECT p " +
                                                    "FROM Podcast p " +
                                                    "WHERE ( lower(p.name) LIKE lower(:word)) " +
                                                    "OR ( lower(p.tags) LIKE lower(:word)) " +
                                                    "OR ( lower(p.user.username) LIKE lower(:word))")
                .setParameter("word", "%"+word.trim()+"%")
                .getResultList();

        if (podcasts.size() != 0) {
            log.info(new Date() + " : Returning list of Podcasts of category with search string : " + word);
        } else {
            podcasts = new ArrayList<Podcast>();
        }

        return podcasts;
    }
}
